﻿using Red.CommUtils.TcpMessageProtocol;
using Red.Core.Network.PacketNetwork;
using System;
using System.Threading.Tasks;

namespace Red.CommUtils.Application
{
    public class ChannelFactory
    {
        PacketNetworkManager _packetManager;

        public ChannelFactory( PacketNetworkManager packetManager )
        {
            _packetManager = packetManager;
        }

        public async Task<IChannel> TryOpenChannel( string name, CommAddress address, int timeout = 60000, int retryDelay = 2000 )
        {
            ChannelConnection connection = new ChannelConnection( _packetManager );
            bool connected = await connection.ConnectTo( address, timeout, retryDelay );

            if ( !connected )
                return null;

            GenericChannel channel = new GenericChannel( connection, name );
            return channel;
        }

        public async Task<IChannel> OpenChannel( string name, CommAddress address )
        {
            const int timeoutInMilliseconds = 60000;

            ChannelConnection connection = new ChannelConnection( _packetManager );
            bool connected = await connection.ConnectTo( address, timeoutInMilliseconds );

            if ( connected == false )
                throw new CommunicationException( "Can't create connection for channel with name " + name );

            GenericChannel channel = new GenericChannel( connection, name );
            return channel;
        }

        public IChannel CreateListenerChannel( string name, CommAddress address )
        {
            ChannelConnection tcpConnection = new ChannelConnection( _packetManager );

            bool listening = tcpConnection.StartListening( address );
            if ( listening == false )
                throw new CommunicationException( "Can't create listener for channel with name " + name );

            return new GenericChannel( tcpConnection, name );
        }
    }
}
